﻿using System;
using System.Linq;

namespace CSharp.Libs.Net
{
    /* Example:
    drwxr-xr-x   8 datenbankftp cust         4096 Dec  3 07:17 .
    drwxr-xr-x   8 datenbankftp cust         4096 Dec  3 07:17 ..
    -rw-r--r--   1 datenbankftp cust         2002 Nov 26 07:02 index.html
    -rw-r--r--   1 datenbankftp cust         1065 Nov 24 12:00 index2.php
    drwxr-xr-x   2 datenbankftp cust         4096 Dec  3 07:15 login
    drwxr-xr-x   3 datenbankftp cust         4096 Nov 21 10:53 phpass-0.3
    drwxr-xr-x   2 datenbankftp cust         4096 Nov 27 20:22 styles
    drwxr-xr-x   2 datenbankftp cust         4096 Nov  1 10:45 styles_old
    drwxr-xr-x   8 datenbankftp cust         4096 Dec  1 15:51 user_managment
    drwxr-xr-x  10 datenbankftp cust         4096 Nov 28 15:21 vwfd_vermittlung
    */

    /// <summary>
    /// represents an entry of a detailed ftp directory list shown in the example above
    /// </summary>
    public class FtpDirectoryDetailedEntry
    {
        #region properties
        public string UnixFlags { get; set; }
        public string Unknown1 { get; set; }
        public string user { get; set; }
        public string group { get; set; }
        public string size { get; set; }
        public string month { get; set; }
        public string day { get; set; }
        public string time { get; set; }
        public string name { get; set; }
        #endregion



        #region static functions
        /// <summary>
        /// tries to parse a line of a detailed ftp directory entry
        /// </summary>
        /// <param name="DirectoryEntry">is the complete line of the detailed ftp directory entry as single string</param>
        /// <param name="fdde">the out FtpDirectoryDetailedEntry object when parsing finished without errors</param>
        /// <returns>true if parsing was successful</returns>
        public static bool TryParse(string DirectoryEntry, out FtpDirectoryDetailedEntry fdde)
        {
            try
            {
                //get pipe separated directory entry
                string result = _replaceWhitespaceWithPipe(DirectoryEntry);

                //create a string array by splitting at pipe
                string[] strarrResults = result.Split('|');

                //detailed directory entry has 9 values
                if (strarrResults.Count() == 9)
                {
                    //entry is valid so create the object
                    fdde = new FtpDirectoryDetailedEntry();
                    fdde.UnixFlags = strarrResults[0];
                    fdde.Unknown1 = strarrResults[1];
                    fdde.user = strarrResults[2];
                    fdde.group = strarrResults[3];
                    fdde.size = strarrResults[4];
                    fdde.month = strarrResults[5];
                    fdde.day = strarrResults[6];
                    fdde.time = strarrResults[7];
                    fdde.name = strarrResults[8];

                    //exit function successful
                    return true;
                }
            }
            catch (Exception ex)
            {
                //unknown exceptions have to be thrown
                throw ex;
            }

            //exit function unsuccessful
            fdde = null;
            return false;
        }

        /// <summary>
        /// replaces all whitespaces inside the WhitespaceString with pipes and returns the result
        /// </summary>
        /// <param name="WhitespaceString">string containing whitespaces</param>
        /// <returns>string containing pipes as separator instead of whitespace</returns>
        private static string _replaceWhitespaceWithPipe(
            string WhitespaceString)
        {
            //prepare result and work variables
            string result = "";
            bool fBlankFound = false;

            //cycle charwise through WhitespaceString
            foreach (char chr in WhitespaceString.ToCharArray())
            {
                if (chr != ' ')
                {
                    //char is not a whitespace. collect in result string.
                    result = string.Concat(result, chr);
                    fBlankFound = false; //unset work switch
                }
                else
                {
                    //char is a whitespace
                    if (!fBlankFound)
                    {
                        //if it is the first found space of the whitespace, add a pipe to the result string
                        result = string.Concat(result, "|");
                        fBlankFound = true;
                    }

                    //ignore the rest of the whitespaces
                }
            }

            //return result
            return result;
        }
        #endregion
    }
}
